#include "wl_mutex.h"

#include "wl_trace.h"

#if defined(WL_OS_MG)
#elif defined(WL_OS_U8910)
#elif defined(WL_OS_QUECTEL)
#    include "ql_rtos.h"
#elif defined(LINUX)
#    include <errno.h>
#else  // default linux
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

wl_int32 wl_mutex_create(const wl_char* name, OUT WL_MUTEX* mutex) {
    if (wl_null != mutex) {
#if defined(WL_OS_MG)
#elif defined(WL_OS_U8910)
        *mutex = SCI_CreateMutex(name, SCI_INHERIT);
        if (SCI_NULL == *mutex) {
            WLLOGW("SCI_CreateMutex fail");
            return -1;
        }
#elif defined(WL_OS_QUECTEL)
        return ql_rtos_mutex_create(mutex);
#else  // default linux
        UNUSED(name);
        pthread_mutexattr_t attr;
        if (pthread_mutexattr_init(&attr)) {
            WLLOGW("pthread_mutexattr_init fail");
            return -1;
        }
        // pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
        if (-1 == pthread_mutex_init(mutex, &attr)) {
            WLLOGW("pthread_mutex_init fail");
            return -1;
        }
#endif
        return 0;
    }
    return -1;
}

wl_int32 wl_mutex_acquire(WL_MUTEX* mutex) {
    if (wl_null != mutex) {
#if defined(WL_OS_MG)
#elif defined(WL_OS_U8910)
        if (SCI_SUCCESS != SCI_GetMutex(*mutex, SCI_WAIT_FOREVER)) {
            WLLOGW("SCI_GetMutex fail");
            return -1;
        }
#elif defined(WL_OS_QUECTEL)
        return ql_rtos_mutex_lock(*mutex, QL_WAIT_FOREVER);
#else
        if (-1 == pthread_mutex_lock(mutex)) {
            WLLOGW("pthread_mutex_lock fail");
            return -1;
        }
#endif
        return 0;
    }
    return -1;
}

wl_int32 wl_mutex_try_acquire(WL_MUTEX* mutex, wl_uint32 timeout) {
    if (wl_null != mutex) {
#if defined(WL_OS_MG)
#elif defined(WL_OS_U8910)
        if (SCI_SUCCESS != SCI_GetMutex(*mutex, timeout)) {
            WLLOGW("SCI_GetMutex fail");
            return -1;
        }
#elif defined(WL_OS_QUECTEL)
        return ql_rtos_mutex_lock(*mutex, timeout);
#else
        UNUSED(timeout);
        wl_int32 error = pthread_mutex_trylock(mutex);
        if (0 != error) {
            WLLOGW("pthread_mutex_trylock fail");
            // if (EBUSY == error) {
            //     return 1;
            // }
            return -1;
        }
#endif
        return 0;
    }
    return -1;
}

wl_int32 wl_mutex_release(WL_MUTEX* mutex) {
    if (wl_null != mutex) {
#if defined(WL_OS_MG)
#elif defined(WL_OS_U8910)
        if (SCI_SUCCESS != SCI_PutMutex(*mutex)) {
            WLLOGW("SCI_PutMutex fail");
            return -1;
        }
#elif defined(WL_OS_QUECTEL)
        return ql_rtos_mutex_unlock(*mutex);
#else
        if (-1 == pthread_mutex_unlock(mutex)) {
            WLLOGW("pthread_mutex_unlock fail");
            return -1;
        }
#endif
        return 0;
    }
    return -1;
}

wl_int32 wl_mutex_delete(WL_MUTEX* mutex) {
    if (wl_null != mutex) {
#if defined(WL_OS_MG)
#elif defined(WL_OS_U8910)
        if (SCI_SUCCESS != SCI_DeleteMutex(*mutex)) {
            WLLOGW("SCI_DeleteMutex fail");
            return -1;
        }
#elif defined(WL_OS_QUECTEL)
        return ql_rtos_mutex_delete(*mutex);
#else
        if (-1 == pthread_mutex_destroy(mutex)) {
            WLLOGW("pthread_mutex_destroy fail");
            return -1;
        }
#endif
        return 0;
    }
    return -1;
}

#ifdef __cplusplus
}
#endif /* __cplusplus */
